
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['WenQuanYi Micro Hei', 'Noto Sans CJK JP', 'DejaVu Sans']
plt.rcParams['axes.unicode_minus'] = False  
import seaborn as sns
from collections import Counter
from itertools import combinations
from matplotlib.widgets import Slider, CheckButtons
from plotly.subplots import make_subplots
import plotly.graph_objects as go
import plotly.express as px
import os
from pathlib import Path

os.environ['QT_QPA_PLATFORM'] = 'xcb'

def load_data(filepath):
    """加载双色球数据"""
    df = pd.read_csv(filepath)
    # 解析红球和篮球
    df['red_balls'] = df['红球'].str.split().apply(lambda x: [int(n) for n in x])
    df['blue_ball'] = df['蓝球'].astype(int)
    return df

def calculate_ac_value(red_balls):
    """计算AC值"""
    diffs = []
    for a, b in combinations(red_balls, 2):
        diffs.append(abs(a - b))
    unique_diffs = len(set(diffs))
    return unique_diffs - (len(red_balls) - 1)


def analyze_red_balls(df):
    """分析红球各项指标"""
    results = []
    for _, row in df.iterrows():
        red = row['red_balls']
        # AC值
        ac = calculate_ac_value(red)
        # 奇偶比
        odd = sum(1 for n in red if n % 2 == 1)
        # 大小比(17为界)
        big = sum(1 for n in red if n >= 17)
        # 区间分布(1-11,12-22,23-33)
        zone1 = sum(1 for n in red if 1 <= n <= 11)
        zone2 = sum(1 for n in red if 12 <= n <= 22)
        zone3 = sum(1 for n in red if 23 <= n <= 33)
        # 和值
        sum_val = sum(red)
        
        results.append({
            'period': row['期号'],
            'redbal': red,
            'AC值': ac,
            '奇偶比': f"{odd}:{6-odd}",
            '大小比': f"{big}:{6-big}",
            '区间分布': f"{zone1}-{zone2}-{zone3}",
            '和值': sum_val
        })
    return pd.DataFrame(results)

def analyze_blue_balls(df):
    """分析篮球各项指标"""
    blue_counts = Counter(df['蓝球'])
    blue_stats = []
    for num in range(1, 17):
        count = blue_counts.get(num, 0)
        is_odd = num % 2 == 1
        is_big = num >= 9
        is_prime = num in {2,3,5,7,11,13}
        blue_stats.append({
            'blue_ball': num,
            'occurrence': count,
            'odd_even': 'Odd' if is_odd else 'Even',
            'big_small': 'Big' if is_big else 'Small',
            'prime_composite': 'Prime' if is_prime else 'Composite'
        })
    return pd.DataFrame(blue_stats)

def visualize_red_analysis(red_df):
    """Visualize red balls analysis results"""
    plt.figure(figsize=(15, 10))
    
    # AC value distribution
    plt.subplot(2, 2, 1)
    sns.histplot(red_df['AC值'], bins=range(3,12), kde=True)
    plt.title('Red Balls AC Value Distribution')
    plt.xlabel('AC Value')
    plt.ylabel('Frequency')
    plt.grid(True, linestyle='--', alpha=0.5)
    
    # Sum value distribution
    plt.subplot(2, 2, 2)
    sns.histplot(red_df['和值'], bins=20, kde=True)
    plt.title('Red Balls Sum Value Distribution')
    plt.xlabel('Sum Value')
    plt.ylabel('Frequency')
    plt.grid(True, linestyle='--', alpha=0.5)
    
    # Odd/Even ratio distribution
    plt.subplot(2, 2, 3)
    red_df['奇偶比'].value_counts().plot(kind='bar')
    plt.title('Red Balls Odd/Even Ratio Distribution')
    plt.xlabel('Odd/Even Ratio')
    plt.ylabel('Count')
    plt.grid(True, linestyle='--', alpha=0.5)
    
    # Big/Small ratio distribution
    plt.subplot(2, 2, 4)
    red_df['大小比'].value_counts().plot(kind='bar')
    plt.title('Red Balls Big/Small Ratio Distribution')
    plt.xlabel('Big/Small Ratio')
    plt.ylabel('Count')
    plt.grid(True, linestyle='--', alpha=0.5)
    
    # plt.figure(constrained_layout=True)
    plt.show()

def visualize_blue_analysis(blue_df):
    """Visualize blue ball analysis results"""
    plt.figure(figsize=(18, 6))
    
    # Blue ball occurrence frequency
    plt.subplot(1, 4, 1)
    sns.barplot(data=blue_df, x='blue_ball', y='occurrence')
    plt.title('Blue Ball Frequency\n(Total: %d)' % blue_df['occurrence'].sum())
    plt.xlabel('Number')
    plt.ylabel('Count')
    plt.grid(True, linestyle='--', alpha=0.5)
    
    # Odd/Even distribution
    plt.subplot(1, 4, 2)
    odd_even_counts = blue_df.groupby('odd_even')['occurrence'].sum()
    sns.barplot(x=odd_even_counts.index, y=odd_even_counts.values, 
               hue=odd_even_counts.index,
               palette=['#3498db', '#e74c3c'],
               legend=False)
    plt.title('Odd/Even Distribution')
    plt.xlabel('Type')
    plt.ylabel('Count')
    plt.grid(True, linestyle='--', alpha=0.5)
    
    # Big/Small distribution
    plt.subplot(1, 4, 3)
    big_small_counts = blue_df.groupby('big_small')['occurrence'].sum()
    sns.barplot(x=big_small_counts.index, y=big_small_counts.values, 
               hue=big_small_counts.index,
               palette=['#2ecc71', '#f39c12'],
               legend=False)
    plt.title('Big/Small Distribution\n(Threshold: 9)')
    plt.xlabel('Type')
    plt.ylabel('Count')
    plt.grid(True, linestyle='--', alpha=0.5)
    
    # Prime/Composite distribution
    plt.subplot(1, 4, 4)
    prime_composite_counts = blue_df.groupby('prime_composite')['occurrence'].sum()
    sns.barplot(
    x=prime_composite_counts.index, 
    y=prime_composite_counts.values,
    hue=prime_composite_counts.index,
    palette=['#9b59b6', '#1abc9c'],
    legend=False
)
    plt.title('Prime/Composite Distribution')
    plt.xlabel('Type')
    plt.ylabel('Count')
    plt.grid(True, linestyle='--', alpha=0.5)
    
    # plt.figure(constrained_layout=True)  # 在创建图形时启用
    plt.show()


def visualize_frequency_charts(df):
    """新增：红球和蓝球频率分布图"""
    plt.figure(figsize=(18, 8))
    
    # 1. 红球频率分布
    plt.subplot(1, 2, 1)
    red_counts = Counter()
    for _, row in df.iterrows():
        red_counts.update(row['red_balls'])
    
    red_df = pd.DataFrame.from_dict(red_counts, orient='index', columns=['出现次数'])
    red_df = red_df.sort_index()
    
    sns.barplot(x=red_df.index, y=red_df['出现次数'], hue=red_df.index, palette='Blues_d', legend=False)
    plt.title('Red Balls Freq')
    plt.xlabel('Red Balls Num')
    plt.ylabel('Occurrence Count')
    plt.grid(True, linestyle='--', alpha=0.3)
    
    # 2. 蓝球频率分布
    plt.subplot(1, 2, 2)
    blue_counts = Counter(df['蓝球'])
    blue_df = pd.DataFrame.from_dict(blue_counts, orient='index', columns=['出现次数'])
    blue_df = blue_df.sort_index()
    
    sns.barplot(x=blue_df.index, y=blue_df['出现次数'], hue=blue_df.index, palette='Reds_d')
    plt.title('Blue Balls Freq')
    plt.xlabel('Blue Balls Num')
    plt.ylabel('Occurrence Count')
    plt.grid(True, linestyle='--', alpha=0.3)
    
    # plt.figure(constrained_layout=True)
    plt.show()

def visualize_hot_cold(df, top_n=10):
    """新增：红球冷热号分析"""
    plt.figure(figsize=(14, 6))
    
    # 红球冷热号
    red_counts = Counter()
    for _, row in df.iterrows():
        red_counts.update(row['red_balls'])
    
    # 获取最热和最冷的号码
    hot_numbers = [num for num, cnt in red_counts.most_common(top_n)]
    cold_numbers = [num for num, cnt in red_counts.most_common()[-top_n:]]
    
    # 准备数据
    hot_data = {num: cnt for num, cnt in red_counts.items() if num in hot_numbers}
    cold_data = {num: cnt for num, cnt in red_counts.items() if num in cold_numbers}
    
    # 绘制热号
    plt.subplot(1, 2, 1)
    hot_df = pd.DataFrame.from_dict(hot_data, orient='index', columns=['出现次数'])
    sns.barplot(x=hot_df.index, y=hot_df['出现次数'], hue=hot_df.index,palette='Reds')
    plt.title(f'Red Balls hot top {top_n} num')
    plt.xlabel('Red Balls Num')
    plt.ylabel('Occurrence Count')
    plt.grid(True, linestyle='--', alpha=0.3)
    
    # 绘制冷号
    plt.subplot(1, 2, 2)
    cold_df = pd.DataFrame.from_dict(cold_data, orient='index', columns=['出现次数'])
    sns.barplot(x=cold_df.index, y=cold_df['出现次数'], hue=cold_df.index, palette='Blues')
    plt.title(f'Red Balls hot top {top_n} num')
    plt.xlabel('Red Balls Num')
    plt.ylabel('Occurrence Count')
    plt.grid(True, linestyle='--', alpha=0.3)
    
    # plt.figure(constrained_layout=True)  # 在创建图形时启用
    plt.show()

if __name__ == "__main__":
    data_dir = Path('/home/ubuntu/mypro/other/ml-pro/project/data')          # 可改成 argparse 參數
    csv_files = sorted(data_dir.glob('*.csv'))

    if not csv_files:
        raise FileNotFoundError('data 目錄下沒有 csv 文件')

    # 2. 逐檔讀入並合併
    df_list = [load_data(f) for f in csv_files]
    df = pd.concat(df_list, ignore_index=True)
    
    # 分析红球
    red_analysis = analyze_red_balls(df)
    red_analysis.to_csv('analysis_result_red.csv', index=False, encoding='utf-8-sig')
    print("Red balls analysis results:")
    print(red_analysis.head())


    # 可視化
    visualize_red_analysis(red_analysis)

    # 分析篮球
    blue_analysis = analyze_blue_balls(df)
    blue_analysis.to_csv('analysis_result_blue.csv', index=False, encoding='utf-8-sig')
    print("\nBlue ball analysis results:")
    print(blue_analysis)


    # 可视化
    visualize_blue_analysis(blue_analysis)
    
    visualize_frequency_charts(df)
    visualize_hot_cold(df)
